<!-- v7 -->
<template>
  <button :class="classNames" :disabled="busy || isDisabled || lockIcon" class="ui-button" type="button">
    <VtsIcon :busy :name="leftIcon" class="icon" size="current" />
    <slot />
    <VtsIcon v-if="lockIcon" name="fa:lock" size="medium" class="icon" />
  </button>
</template>

<script lang="ts" setup>
import VtsIcon from '@core/components/icon/VtsIcon.vue'
import { useDisabled } from '@core/composables/disabled.composable'
import type { IconName } from '@core/icons'
import { toVariants } from '@core/utils/to-variants.util'
import { computed } from 'vue'

export type ButtonVariant = 'primary' | 'secondary' | 'tertiary'
export type ButtonAccent = 'brand' | 'warning' | 'danger'
export type ButtonSize = 'small' | 'medium'

export type ButtonProps = {
  variant: ButtonVariant
  accent: ButtonAccent
  size: ButtonSize
  busy?: boolean
  disabled?: boolean
  lockIcon?: boolean
  leftIcon?: IconName
}

const { accent, variant, size, disabled, busy, lockIcon } = defineProps<ButtonProps>()

defineSlots<{
  default(): any
}>()

const isDisabled = useDisabled(() => disabled)

const fontClasses = {
  small: 'typo-action-button-small',
  medium: 'typo-action-button',
  large: 'typo-h3',
}

const classNames = computed(() => [
  fontClasses[size],
  toVariants({
    accent,
    variant,
    size,
    busy,
    lock: lockIcon,
    disabled: isDisabled.value,
  }),
])
</script>

<style lang="postcss" scoped>
/* IMPLEMENTATION */
.ui-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  vertical-align: middle;
  gap: 0.75em;
  border-width: 0.1rem;
  outline: none;
  border-style: solid;

  &.lock {
    cursor: default;
  }

  &:focus-visible {
    outline: none;

    &::before {
      content: '';
      position: absolute;
      inset: -0.5rem;
      border-radius: 0.4rem;
      border-width: 0.2rem;
      border-style: solid;
    }
  }

  .icon {
    font-size: 0.8em;
  }

  /* ACCENT + VARIANT */

  &.accent--brand {
    &.variant--primary {
      background-color: var(--color-brand-item-base);
      border-color: var(--color-brand-item-base);
      color: var(--color-brand-txt-item);

      &:hover {
        background-color: var(--color-brand-item-hover);
        border-color: var(--color-brand-item-hover);
        color: var(--color-brand-txt-item);
      }

      &:focus-visible::before {
        border-color: var(--color-brand-txt-base);
      }

      &:active {
        background-color: var(--color-brand-item-active);
        border-color: var(--color-brand-item-active);
        color: var(--color-brand-txt-item);
      }

      &:is(:disabled, .disabled, .busy) {
        background-color: var(--color-brand-item-disabled);
        border-color: var(--color-brand-item-disabled);
        color: var(--color-neutral-txt-secondary);
      }
    }

    &.variant--secondary {
      background-color: var(--color-neutral-background-primary);
      border-color: var(--color-brand-item-base);
      color: var(--color-brand-txt-base);

      &:hover {
        background-color: var(--color-neutral-background-primary);
        border-color: var(--color-brand-item-hover);
        color: var(--color-brand-txt-hover);
      }

      &:focus-visible::before {
        border-color: var(--color-brand-txt-base);
      }

      &:active {
        background-color: var(--color-neutral-background-primary);
        border-color: var(--color-brand-item-active);
        color: var(--color-brand-txt-active);
      }

      &:is(:disabled, .disabled, .busy) {
        background-color: var(--color-neutral-background-disabled);
        border-color: var(--color-neutral-txt-secondary);
        color: var(--color-neutral-txt-secondary);
      }
    }

    &.variant--tertiary {
      background-color: transparent;
      border-color: transparent;
      color: var(--color-brand-txt-base);

      &:hover {
        background-color: var(--color-brand-background-hover);
        border-color: var(--color-brand-background-hover);
        color: var(--color-brand-txt-hover);
      }

      &:focus-visible::before {
        border-color: var(--color-brand-txt-base);
      }

      &:active {
        background-color: var(--color-brand-background-active);
        border-color: var(--color-brand-background-active);
        color: var(--color-brand-txt-active);
      }

      &:is(:disabled, .disabled, .busy) {
        background-color: transparent;
        border-color: transparent;
        color: var(--color-neutral-txt-secondary);
      }
    }
  }

  &.accent--warning {
    &.variant--primary {
      background-color: var(--color-warning-item-base);
      border-color: var(--color-warning-item-base);
      color: var(--color-warning-txt-item);

      &:hover {
        background-color: var(--color-warning-item-hover);
        border-color: var(--color-warning-item-hover);
        color: var(--color-warning-txt-item);
      }

      &:focus-visible::before {
        border-color: var(--color-brand-txt-base);
      }

      &:active {
        background-color: var(--color-warning-item-active);
        border-color: var(--color-warning-item-active);
        color: var(--color-warning-txt-item);
      }

      &:is(:disabled, .disabled, .busy) {
        background-color: var(--color-warning-item-disabled);
        border-color: var(--color-warning-item-disabled);
        color: var(--color-neutral-txt-secondary);
      }
    }

    &.variant--secondary {
      background-color: var(--color-neutral-background-primary);
      border-color: var(--color-warning-txt-base);
      color: var(--color-warning-txt-base);

      &:hover {
        background-color: var(--color-neutral-background-primary);
        border-color: var(--color-warning-txt-hover);
        color: var(--color-warning-txt-hover);
      }

      &:focus-visible::before {
        border-color: var(--color-brand-txt-base);
      }

      &:active {
        background-color: var(--color-neutral-background-primary);
        border-color: var(--color-warning-txt-active);
        color: var(--color-warning-txt-active);
      }

      &:is(:disabled, .disabled, .busy) {
        background-color: var(--color-neutral-background-disabled);
        border-color: var(--color-neutral-txt-secondary);
        color: var(--color-neutral-txt-secondary);
      }
    }

    &.variant--tertiary {
      background-color: transparent;
      border-color: transparent;
      color: var(--color-warning-txt-base);

      &:hover {
        background-color: var(--color-warning-background-hover);
        border-color: var(--color-warning-background-hover);
        color: var(--color-warning-txt-hover);
      }

      &:focus-visible::before {
        border-color: var(--color-brand-txt-base);
      }

      &:active {
        background-color: var(--color-warning-background-active);
        border-color: var(--color-warning-background-active);
        color: var(--color-warning-txt-active);
      }

      &:is(:disabled, .disabled, .busy) {
        background-color: transparent;
        border-color: transparent;
        color: var(--color-neutral-txt-secondary);
      }
    }
  }

  &.accent--danger {
    &.variant--primary {
      background-color: var(--color-danger-item-base);
      border-color: var(--color-danger-item-base);
      color: var(--color-danger-txt-item);

      &:hover {
        background-color: var(--color-danger-item-hover);
        border-color: var(--color-danger-item-hover);
        color: var(--color-danger-txt-item);
      }

      &:focus-visible::before {
        border-color: var(--color-brand-txt-base);
      }

      &:active {
        background-color: var(--color-danger-item-active);
        border-color: var(--color-danger-item-active);
        color: var(--color-danger-txt-item);
      }

      &:is(:disabled, .disabled, .busy) {
        background-color: var(--color-danger-item-disabled);
        border-color: var(--color-danger-item-disabled);
        color: var(--color-neutral-txt-secondary);
      }
    }

    &.variant--secondary {
      background-color: var(--color-neutral-background-primary);
      border-color: var(--color-danger-txt-base);
      color: var(--color-danger-txt-base);

      &:hover {
        background-color: var(--color-neutral-background-primary);
        border-color: var(--color-danger-txt-hover);
        color: var(--color-danger-txt-hover);
      }

      &:focus-visible::before {
        border-color: var(--color-brand-txt-base);
      }

      &:active {
        background-color: var(--color-neutral-background-primary);
        border-color: var(--color-danger-txt-active);
        color: var(--color-danger-txt-active);
      }

      &:is(:disabled, .disabled, .busy) {
        background-color: var(--color-neutral-background-disabled);
        border-color: var(--color-neutral-txt-secondary);
        color: var(--color-neutral-txt-secondary);
      }
    }

    &.variant--tertiary {
      background-color: transparent;
      border-color: transparent;
      color: var(--color-danger-txt-base);

      &:hover {
        background-color: var(--color-danger-background-hover);
        border-color: var(--color-danger-background-hover);
        color: var(--color-danger-txt-hover);
      }

      &:focus-visible::before {
        border-color: var(--color-brand-txt-base);
      }

      &:active {
        background-color: var(--color-danger-background-active);
        border-color: var(--color-danger-background-active);
        color: var(--color-danger-txt-active);
      }

      &:is(:disabled, .disabled, .busy) {
        background-color: transparent;
        border-color: transparent;
        color: var(--color-neutral-txt-secondary);
      }
    }
  }

  /* SIZE */

  &.size--small {
    padding: 0.8rem;
    border-radius: 0.2rem;
  }

  &.size--medium {
    padding: 1.2rem 1.6rem;
    border-radius: 0.4rem;
  }
}
</style>
